home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / pas / swag / datetime.swg / 0027_Calculate Day Of Week.pas < prev    next >
Pascal/Delphi Source File  |  1993-11-02  |  3KB  |  70 lines

  1. {
  2. EARL DUNOVANT
  3.  
  4. > Which date is what day For a particular month.
  5.  
  6. Zeller's Congruence is an algorithm that calculates a day of the week given
  7. a year, month and day. Created in 1887(!). Jeff Duntemann of PC Techniques
  8. fame implemented it in TP in the 11/90 issue of Dr Dobbs Journal, With a
  9. (115 min left), (H)elp, More? major kludge because TP's MOD operator returns a remainder instead of a
  10. True mathematical modulus. I added the Kludge Alert banner that I use in my
  11. own code.
  12. }
  13.  
  14. Function CalcDayOfWeek(Year, Month, Day : Integer) : Integer;
  15. Var
  16.   Century,
  17.   Holder  : Integer;
  18. begin
  19.   { First test For error conditions on input values: }
  20.   if (Year < 0) or (Month < 1) or (Month > 12) or (Day < 1) or (Day > 31) then
  21.     CalcDayOfWeek := -1  { Return -1 to indicate an error }
  22.   else
  23.   { Do the Zeller's Congruence calculation as Zeller himself }
  24.   { described it in "Acta Mathematica" #7, Stockhold, 1887.  }
  25.   begin
  26.     { First we separate out the year and the century figures: }
  27.     Century := Year div 100;
  28.     Year    := Year MOD 100;
  29.     { Next we adjust the month such that March remains month #3, }
  30.     { but that January and February are months #13 and #14,     }
  31.     { *but of the previous year*: }
  32.     if Month < 3 then
  33.     begin
  34.       Inc(Month, 12);
  35.       if Year > 0 then
  36.         Dec(Year, 1)      { The year before 2000 is }
  37.       else              { 1999, not 20-1...       }
  38.       begin
  39.         Year := 99;
  40.         Dec(Century);
  41.       end;
  42.     end;
  43.  
  44.     { Here's Zeller's seminal black magic: }
  45.     Holder := Day;                        { Start With the day of month }
  46.     Holder := Holder + (((Month + 1) * 26) div 10); { Calc the increment }
  47.     Holder := Holder + Year;              { Add in the year }
  48.     Holder := Holder + (Year div 4);      { Correct For leap years  }
  49.     Holder := Holder + (Century div 4);   { Correct For century years }
  50.     Holder := Holder - Century - Century; { DON'T KNOW WHY HE DID THIS! }
  51.     {***********************KLUDGE ALERT!***************************}
  52.     While Holder < 0 do                   { Get negative values up into }
  53.       Inc(Holder, 7);                     { positive territory before   }
  54.                                           { taking the MOD...         }
  55.     Holder := Holder MOD 7;               { Divide by 7 but keep the  }
  56.                                           { remainder rather than the }
  57.                                           { quotient }
  58.     {***********************KLUDGE ALERT!***************************}
  59.     { Here we "wrap" Saturday around to be the last day: }
  60.     if Holder = 0 then
  61.       Holder := 7;
  62.  
  63.     { Zeller kept the Sunday = 1 origin; computer weenies prefer to }
  64.     { start everything With 0, so here's a 20th century kludge:     }
  65.     Dec(Holder);
  66.  
  67.     CalcDayOfWeek := Holder;  { Return the end product! }
  68.   end;
  69. end;
  70.